﻿using System;
using System.Linq;
using Cesave.Domain.PermisosModule.Contracts.CiclosFechas;
using Cesave.Domain.PermisosModule.Entities;
using Cesave.Infrastructure.CrossCutting.Logging;
using Cesave.Infrastructure.Data.PermisosModule.Context;
using Cesave.Infrastructure.Data.PermisosModule.Repositories;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace Cesave.Infrastructure.Data.PermisosModule.Tests.RepositoriesTests
{
	[TestClass]
	public class CiclosFechaRepositoryTests
		: GenericRepositoryTestsBase<CiclosFecha>
	{
		public override System.Linq.Expressions.Expression<Func<CiclosFecha, bool>> FilterExpression
		{
			get
			{
				return f => f.FechaId == 1;
			}
		}

		public override System.Linq.Expressions.Expression<Func<CiclosFecha, int>> OrderByExpression
		{
			get
			{
				return f => f.FechaId;
			}
		}

		[TestMethod]
		[ExpectedException(typeof(ArgumentNullException))]
		public void FindCiclosFechasByJuntaAndCiclo_Null_Specification_Throws_ArgumentNullException()
		{
			// Arrange
			IPermisosModuleContext context = GetContext();
			ITraceManager traceManager = GetTraceManager();
			ICiclosFechaRepository repository = new CiclosFechaRepository(context, traceManager);

			// Act
			var actual = repository.FindCiclosFechasByJuntaAndCiclo(null, null);
		}

		[TestMethod]
		[ExpectedException(typeof(ArgumentException))]
		public void FindCiclosFechasByJuntaAndCiclo_Empty_Guid_Throws_ArgumentException()
		{
			// Arrange
			IPermisosModuleContext context = GetContext();
			ITraceManager traceManager = GetTraceManager();
			ICiclosFechaRepository repository = new CiclosFechaRepository(context, traceManager);

			var guid = Guid.Empty;

			var spec1 = new CiclosFechasByJuntaSpecification(guid);
			var spec2 = new CiclosFechasByCicloSpecification(guid);

			// Act
			var actual = repository.FindCiclosFechasByJuntaAndCiclo(spec1, spec2);
		}

		[TestMethod]
		public void FindCiclosFechasByJuntaAndCiclo_Invoke()
		{
			// Arrange
			IPermisosModuleContext context = GetContext();
			ITraceManager traceManager = GetTraceManager();
			ICiclosFechaRepository repository = new CiclosFechaRepository(context, traceManager);

			var juntaGuid = new Guid("C1F6907F-9F13-46EA-981E-2E6DB652AAF2");
			var cicloGuid = new Guid("ED77E3AC-1E91-44EA-9F80-C9B2619B9211");

			// Act
			var actual = repository.FindCiclosFechasByJuntaAndCiclo(new CiclosFechasByJuntaSpecification(juntaGuid), new CiclosFechasByCicloSpecification(cicloGuid));

			// Assert
			Assert.IsNotNull(actual);
			Assert.AreEqual(4, actual.Count());
			actual.ToList().ForEach((a) =>
			{
				Assert.AreEqual(a.JuntaGuid, juntaGuid);
				Assert.AreEqual(a.CicloGuid, cicloGuid);
			});
		}

		[TestMethod]
		[ExpectedException(typeof(ArgumentNullException))]
		public void FindCiclosFechasByJuntaAndCicloAndDateRange_Null_Specification_Throws_ArgumentNullException()
		{
			// Arrange
			IPermisosModuleContext context = GetContext();
			ITraceManager traceManager = GetTraceManager();
			ICiclosFechaRepository repository = new CiclosFechaRepository(context, traceManager);

			// Act
			var actual = repository.FindCiclosFechasByJuntaAndCicloAndDateRange(null, null, null);
		}

		[TestMethod]
		[ExpectedException(typeof(ArgumentException))]
		public void FindCiclosFechasByJuntaAndCicloAndDateRange_Empty_Guid_Throws_ArgumentException()
		{
			// Arrange
			IPermisosModuleContext context = GetContext();
			ITraceManager traceManager = GetTraceManager();
			ICiclosFechaRepository repository = new CiclosFechaRepository(context, traceManager);

			var guid = Guid.Empty;

			var spec1 = new CiclosFechasByJuntaSpecification(guid);
			var spec2 = new CiclosFechasByCicloSpecification(guid);
			var spec3 = new CiclosFechasByDateRangeSpecification(DateTime.Now, DateTime.Now);

			// Act
			var actual = repository.FindCiclosFechasByJuntaAndCicloAndDateRange(spec1, spec2, spec3);
		}

		[TestMethod]
		[ExpectedException(typeof(ArgumentException))]
		public void FindCiclosFechasByJuntaAndCicloAndDateRange_MinValue_Date_Throws_ArgumentException()
		{
			// Arrange
			IPermisosModuleContext context = GetContext();
			ITraceManager traceManager = GetTraceManager();
			ICiclosFechaRepository repository = new CiclosFechaRepository(context, traceManager);

			var guid = Guid.NewGuid();

			DateTime fromDate = DateTime.MinValue;
			DateTime toDate = DateTime.MinValue;

			var spec1 = new CiclosFechasByJuntaSpecification(guid);
			var spec2 = new CiclosFechasByCicloSpecification(guid);
			var spec3 = new CiclosFechasByDateRangeSpecification(fromDate, toDate);

			// Act
			var actual = repository.FindCiclosFechasByJuntaAndCicloAndDateRange(spec1, spec2, spec3);
		}

		[TestMethod]
		public void FindCiclosFechasByJuntaAndCicloAndDateRange_Invoke()
		{
			// Arrange
			IPermisosModuleContext context = GetContext();
			ITraceManager traceManager = GetTraceManager();
			ICiclosFechaRepository repository = new CiclosFechaRepository(context, traceManager);

			var juntaGuid = new Guid("A827881A-8EC9-4187-879A-192BEF55A0F6");
			var cicloGuid = new Guid("ED77E3AC-1E91-44EA-9F80-C9B2619B9211");

			DateTime fromDate = new DateTime(2010, 05, 02);
			DateTime toDate = new DateTime(2010, 07, 15);

			var spec1 = new CiclosFechasByJuntaSpecification(juntaGuid);
			var spec2 = new CiclosFechasByCicloSpecification(cicloGuid);
			var spec3 = new CiclosFechasByDateRangeSpecification(fromDate, toDate);

			// Act
			var actual = repository.FindCiclosFechasByJuntaAndCicloAndDateRange(spec1, spec2, spec3);

			// Assert
			Assert.IsNotNull(actual);
			actual.ToList().ForEach((a) =>
			{
				Assert.AreEqual(cicloGuid, a.CicloGuid);
				Assert.AreEqual(juntaGuid, a.JuntaGuid);
				Assert.IsTrue(a.Inicio >= fromDate);
				Assert.IsTrue(a.Fin <= toDate);
			});
		}
	}
}